use pest::Parser;
use pest::iterators::Pairs;
use pest_derive::Parser;

use crate::error::SyntaxError;
use pest::error::LineColLocation;

#[derive(Parser)]
#[grammar = "src/parser.pest"] // 引入语法规则
struct SysYParser;


// 封装语法分析
pub fn parse(input: &str) -> Result<String, Vec<SyntaxError>> {
    let pairs = SysYParser::parse(Rule::program, input);

    match pairs {
        Ok(p) => {
            let formatted = format_code(p);
            Ok(formatted)
        }
        Err(e) => {
            let mut errors = Vec::new();
            let lcl = e.line_col(input);
            let line = match lcl {
                LineColLocation::Pos((line, _col)) => line,
                LineColLocation::Span((line, _col)) => line,
            };
            errors.push(SyntaxError {
                line: 1,
                msg: format!("unexpected token: {}", e.variant.message()),
            });
            Err(errors)
        }
    }
}

/// 遍历语法树并格式化输出
fn format_code(pairs: Pairs<Rule>) -> String {
    let mut out = String::new();
    for pair in pairs {
        out.push_str(&pair.as_str());
        out.push('\n');
    }
    out
}

